home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1993 November / JCSM Shareware Collection - 1993-11.iso / cl720 / sst115j.lzh / SSTVID.C < prev    next >
C/C++ Source or Header  |  1992-07-18  |  21KB  |  670 lines

  1. /* ------------------------------------------------------------------------ */
  2. /*                                 sstvid.c                                 */
  3. /*                                                                          */
  4. /*                         low-level video functions                        */
  5. /*                                                                          */
  6. /*      CopyRight (C) 1991,1992  Steven Lutrov.   All rights reserved.      */
  7. /* ------------------------------------------------------------------------ */
  8. #include <dos.h>
  9. #include <bios.h>
  10. #include <stdio.h>
  11. #include <stdarg.h>
  12. #include <alloc.h>
  13. #include <string.h>
  14.  
  15. #include "sstvid.h"
  16.  
  17. /* ------------------------------------------------------------------------ */
  18. /*                        video BIOS (0x10) functions                       */
  19. /* ------------------------------------------------------------------------ */
  20. #define SETCURSORTYPE        0x01
  21. #define SETCURSOR            0x02
  22. #define READCURSOR           0x03
  23. #define READATTRCHAR         0x08
  24. #define WRITEATTRCHAR        0x09
  25. #define HIDECURSOR           0x20
  26.  
  27. #define ZEROFLAG             0x40    /* zero flag mask  */
  28. #define MAXCSAVES              50    /* maximun cursor saves  */
  29. #define MAXSSAVES              12    /* maximun screen saves  */
  30.  
  31. #define VIDSEGREG (unsigned)((7 == VIDMODE) ? 0xb000 : 0xb800 )
  32. #define SCRSIZE   (SCREENWIDTH * SCREENHEIGHT * 2)
  33.  
  34. /* ------------------------------------------------------------------------ */
  35. /*                          local prototypes                                */
  36. /* ------------------------------------------------------------------------ */
  37. static void near getcursor (void);
  38. static void scan350        (void);
  39. static void scan400        (void);
  40. static void getvmode       (void);
  41. static unsigned char far *currentpos (void);
  42. static unsigned char far *scrptr (int x, int y);
  43.  
  44. /* ------------------------------------------------------------------------ */
  45. /*                           local variables                                */
  46. /* ------------------------------------------------------------------------ */
  47. static int near cursorpos[MAXCSAVES];    /* cursor position buffer */
  48. static int near cursorshape[MAXCSAVES];  /* cursor shape buffer */
  49. static int cs = 0;                       /* cursor save counter */
  50. static char far *scrarray[MAXSSAVES];
  51. static int ss = -1;                      /* screen save counter */
  52.  
  53. unsigned int vmode;                      /* video mode */
  54. unsigned int vpage;                      /* video page number */
  55.  
  56. /* ------------------------------------------------------------------------ */
  57. /*              clear the screen in a given attribute by scrolling          */
  58. /* ------------------------------------------------------------------------ */
  59. void vcls(unsigned char attr)
  60.  
  61. {
  62.     _AH = 0x06;                       /* scroll window up */
  63.     _AL = 0;                          /* clear entire window */
  64.     _BH = attr;
  65.     _CX = 0;                          /* upper left = (0,0) */
  66.     _DH = SCREENHEIGHT-1;
  67.     _DL = SCREENWIDTH-1;
  68.     geninterrupt(VIDEO);
  69. }
  70.  
  71. /* ------------------------------------------------------------------------ */
  72. /*                            clear a given line                            */
  73. /* ------------------------------------------------------------------------ */
  74. void vclearline(unsigned char row, unsigned char attr)
  75.  
  76. {
  77.     _AH = 0x06;                       /* scroll window up */
  78.     _AL = 1;                          /* clear 1 line */
  79.     _BH = attr;
  80.     _CH = row;                        /* upper left = (row,0) */
  81.     _CL = 0;
  82.     _DH = row;                        /* lower right = (row,79) */
  83.     _DL = SCREENWIDTH-1;
  84.     geninterrupt(VIDEO);
  85. }
  86.  
  87. /* ------------------------------------------------------------------------ */
  88. /*                           position the cursor                            */
  89. /* ------------------------------------------------------------------------ */
  90. void vsetcur(int x, int y)
  91. {
  92.     getvmode();
  93.     _DX = ((y << 8) & 0xFF00) + x;
  94.     _AH = SETCURSOR;
  95.     _BX = vpage;
  96.     geninterrupt(VIDEO);
  97. }
  98.  
  99. /* ------------------------------------------------------------------------ */
  100. /*                   return the current cursor position                     */
  101. /* ------------------------------------------------------------------------ */
  102. void vgetcur(int *x, int *y)
  103. {
  104.     getcursor();
  105.     *x = _DL;
  106.     *y = _DH;
  107. }
  108.  
  109. /* ------------------------------------------------------------------------ */
  110. /*                         use BIOS set cursor type                         */
  111. /* ------------------------------------------------------------------------ */
  112. void vsetcurtype(unsigned t)
  113. {
  114.     getvmode();
  115.     _AH = SETCURSORTYPE;
  116.     _BX = vpage;
  117.     _CX = t;
  118.     geninterrupt(VIDEO);
  119. }
  120.  
  121.  
  122. /* ------------------------------------------------------------------------ */
  123. /*                            test for scroll lock                          */
  124. /* ------------------------------------------------------------------------ */
  125. int Kscrolllock()
  126. {
  127.     _AX = 0x0200;
  128.     geninterrupt(VIDEO);
  129.     return _AL & 0x10;
  130. }
  131.  
  132.  
  133. void (*helpfunc)(void);  /* function prototype */
  134. int helpkey = 0;
  135. int helping = 0;
  136.  
  137. /* ------------------------------------------------------------------------ */
  138. /*        get a keyboard character  and hooks help if help is required      */
  139. /* ------------------------------------------------------------------------ */
  140. unsigned int kgetch(void)
  141. {
  142.     unsigned int c;
  143.  
  144.     while (1)    {
  145.         _AH = 0x01;
  146.         geninterrupt(KEYBRD);
  147.         if (_FLAGS & 0x40)    {
  148.              geninterrupt(KBUSYLOOP);
  149.             continue;
  150.         }
  151.         _AH = 0x00;
  152.         geninterrupt(KEYBRD);
  153.     c = (_AL > 0 && _AL < 127) ? _AL : _AX;
  154.     if (c == helpkey && helpfunc)   {
  155.             if (!helping)    {
  156.                 helping = 1;
  157.                 (*helpfunc)();
  158.                 helping = 0;
  159.                 continue;
  160.             }
  161.         }
  162.         break;
  163.     }
  164.     return c;
  165. }
  166.  
  167. /* ------------------------------------------------------------------------ */
  168. /*   get a keyboard char (extended kbd) and hooks help if help is required  */
  169. /* ------------------------------------------------------------------------ */
  170. unsigned int kgetche(void)
  171. {
  172.     unsigned int c;
  173.  
  174.     while (1)    {
  175.         _AH = 0x11;
  176.     geninterrupt(KEYBRD);
  177.         if (_FLAGS & ZEROFLAG)  {
  178.              geninterrupt(KBUSYLOOP);
  179.             continue;
  180.         }
  181.         _AH = 0x10;
  182.         geninterrupt(KEYBRD);
  183.     c = (_AL > 0 && _AL < 127) ? _AL : _AX;
  184.     if (c == helpkey && helpfunc)   {
  185.             if (!helping)    {
  186.                 helping = 1;
  187.                 (*helpfunc)();
  188.                 helping = 0;
  189.                 continue;
  190.             }
  191.         }
  192.         break;
  193.     }
  194.     return c;
  195. }
  196.  
  197. /* ------------------------------------------------------------------------ */
  198. /*                            Test for keystroke                            */
  199. /* ------------------------------------------------------------------------ */
  200. int kkeyhit(void)
  201. {
  202.     _AH = 0x11;
  203.     geninterrupt(KEYBRD);
  204.     return (_FLAGS & ZEROFLAG) == 0;
  205. }
  206.  
  207. /* ------------------------------------------------------------------------ */
  208. /*                  save the current cursor configuration                   */
  209. /* ------------------------------------------------------------------------ */
  210. void vpushcur(void)
  211. {
  212.     if (cs < MAXCSAVES)    {
  213.     getcursor();
  214.     cursorshape[cs] = _CX;
  215.     cursorpos[cs] = _DX;
  216.     cs++;
  217.     }
  218. }
  219.  
  220. /* ------------------------------------------------------------------------ */
  221. /*                 restore the saved cursor configuration                   */
  222. /* ------------------------------------------------------------------------ */
  223. void vpopcur(void)
  224. {
  225.     if (cs)    {
  226.       --cs;
  227.       getvmode();
  228.       _DX = cursorpos[cs];
  229.       _AH = SETCURSOR;
  230.       _BX = vpage;
  231.       geninterrupt(VIDEO);
  232.       vsetcurtype(cursorshape[cs]);
  233.     }
  234. }
  235.  
  236. /* ------------------------------------------------------------------------ */
  237. /*                         make a normal cursor                             */
  238. /* ------------------------------------------------------------------------ */
  239. void vnormalcur(void)
  240. {
  241.     vsetcurtype(0x0607);
  242. }
  243.  
  244. /* ------------------------------------------------------------------------ */
  245. /*                           hide the cursor                                */
  246. /* ------------------------------------------------------------------------ */
  247. void vhidecur(void)
  248. {
  249.     getcursor();
  250.     _CH |= HIDECURSOR;
  251.     _AH = SETCURSORTYPE;
  252.     geninterrupt(VIDEO);
  253. }
  254.  
  255. /* ------------------------------------------------------------------------ */
  256. /*                             unhide the cursor                            */
  257. /* ------------------------------------------------------------------------ */
  258. void vshowcur(void)
  259. {
  260.     getcursor();
  261.     _CH &= ~HIDECURSOR;
  262.     _AH = SETCURSORTYPE;
  263.     geninterrupt(VIDEO);
  264. }
  265.  
  266.  
  267. /* ------------------------------------------------------------------------ */
  268. /*                               test for EGA                               */
  269. /* ------------------------------------------------------------------------ */
  270. int visega(void)
  271. {
  272.     if (visvga())
  273.     return 0;
  274.     _AH = 0x12;
  275.     _BL = 0x10;
  276.     geninterrupt(VIDEO);
  277.     return (_BL != 0x10);
  278. }
  279.  
  280. /* ------------------------------------------------------------------------ */
  281. /*                               test for VGA                               */
  282. /* ------------------------------------------------------------------------ */
  283. int visvga(void)
  284. {
  285.     _AX = 0x1a00;
  286.     geninterrupt(VIDEO);
  287.     return _AL == 0x1A && _BL > 6;
  288. }
  289.  
  290. /* ------------------------------------------------------------------------ */
  291. /*                            set 25 line mode                              */
  292. /* ------------------------------------------------------------------------ */
  293. void vset25(void)
  294. {
  295.     if (visvga())
  296.     scan400();
  297.     _AX = (visvga()  ? 0x1114  : 0x1111);
  298.     _BX = 0;
  299.     geninterrupt(VIDEO);
  300. }
  301.  
  302. /* ------------------------------------------------------------------------ */
  303. /*                           set 43 line mode                               */
  304. /* ------------------------------------------------------------------------ */
  305. void vset43(void)
  306. {
  307.     if (visvga())
  308.     scan350();
  309.     _AX = 0x1112;
  310.     _BX = 0;
  311.     geninterrupt(VIDEO);
  312. }
  313.  
  314. /* ------------------------------------------------------------------------ */
  315. /*                            set 50 line mode                              */
  316. /* ------------------------------------------------------------------------ */
  317. void vset50(void)
  318. {
  319.     if (visvga())
  320.     scan400();
  321.     _AX = 0x1112;
  322.     _BX = 0;
  323.     geninterrupt(VIDEO);
  324. }
  325.  
  326.  
  327.  
  328. /* ------------------------------------------------------------------------ */
  329. /*                      Toggle intensity/blinking bit                       */
  330. /* ------------------------------------------------------------------------ */
  331. void vblinkbit(int f)       /* NOTE - only valid for EGA/VGA systems */
  332. {
  333.    _BL = f;
  334.    _BH = 0;
  335.    _AX = 0x1003;
  336.    geninterrupt(VIDEO);
  337. }
  338.  
  339.  
  340. int far *kbd_status = (int far *) 0x00000417L;
  341.  
  342. /* ------------------------------------------------------------------------ */
  343. /*          return the state of all the keys by peeking into bios           */
  344. /* ------------------------------------------------------------------------ */
  345. int far *kstate(void)
  346.  
  347. {
  348.    return (kbd_status);
  349. }
  350.  
  351.  
  352. /* ------------------------------------------------------------------------ */
  353. /*             put a char and attribute at the given coordinates            */
  354. /* ------------------------------------------------------------------------ */
  355. void vputch(int x, int y, unsigned char a, register unsigned char c)
  356. {
  357.     register unsigned char far *p;
  358.  
  359.     p = scrptr(x,y);
  360.     *p++ = c;
  361.     *p++ = a;
  362. }
  363.  
  364. /* ------------------------------------------------------------------------ */
  365. /*                  put a string at the given coordinates                   */
  366. /* ------------------------------------------------------------------------ */
  367. void vputs(int x, int y, unsigned char a, register char *s )
  368. {
  369.     register unsigned char far *p;
  370.  
  371.     p = scrptr(x,y);
  372.     while (*s) {
  373.          *p++ = *s++;
  374.          *p++ = a;
  375.     }
  376. }
  377.  
  378. /* ------------------------------------------------------------------------ */
  379. /*             put a formatted string at the given coordinates              */
  380. /* ------------------------------------------------------------------------ */
  381. void vputf( int x, int y, unsigned char a, char *fmt, ... )
  382. {
  383.     register unsigned char far *p;
  384.     char s[120];
  385.     register char *cp = s;
  386.     va_list argptr;
  387.  
  388.     va_start( argptr, fmt );
  389.     vsprintf( s, fmt, argptr );
  390.     va_end( argptr );
  391.  
  392.     p = scrptr(x,y);
  393.     while (*cp) {
  394.          *p++ = *cp++;
  395.          *p++ = a;
  396.     }
  397. }
  398.  
  399. /* ------------------------------------------------------------------------ */
  400. /*                    put a string centered on a given line                 */
  401. /* ------------------------------------------------------------------------ */
  402. void vputsc( int y, unsigned char a, char *s )
  403. {
  404.     vputs ( ( 80 - strlen(s) ) / 2, y, a, s );
  405. }
  406.  
  407. /* ------------------------------------------------------------------------ */
  408. /*      put a formatted and centered string at the given coordinates        */
  409. /* ------------------------------------------------------------------------ */
  410. void vputfc(int y, unsigned char a, char *fmt, ... )
  411. {
  412.     char s[120];
  413.     va_list ap;
  414.  
  415.     va_start( ap, fmt );
  416.     vsprintf( s, fmt, ap );
  417.     va_end( ap );
  418.  
  419.     vputs( ( 80 - strlen(s) ) / 2, y, a, s );
  420. }
  421.  
  422. /* ------------------------------------------------------------------------ */
  423. /*               return the attribute at the given coordinates              */
  424. /* ------------------------------------------------------------------------ */
  425. int vgeta(int x, int y)
  426. {
  427.      unsigned char far *p;
  428.  
  429.      p = scrptr(x,y);
  430.      return(*(++p));
  431. }
  432.  
  433. /* ------------------------------------------------------------------------ */
  434. /*               return the character at the given coordinates              */
  435. /* ------------------------------------------------------------------------ */
  436. int vgetch(int x, int y)
  437. {
  438.      unsigned char far *p;
  439.  
  440.      p = scrptr(x,y);
  441.      return(*p++);
  442. }
  443.  
  444. /* ------------------------------------------------------------------------ */
  445. /*        return the character and attribute at the given coordinates       */
  446. /* ------------------------------------------------------------------------ */
  447. int vget(int x, int y)
  448. {
  449.      int far *p;
  450.  
  451.      p = (int far*) scrptr(x,y);
  452.      return(*p++);
  453. }
  454.  
  455. /* ------------------------------------------------------------------------ */
  456. /*          return the attribute at the current cursor coordinates          */
  457. /* ------------------------------------------------------------------------ */
  458. int vgetac(void)
  459. {
  460.      unsigned char far *scptr = currentpos();
  461.      return( *(++scptr));
  462. }
  463.  
  464. /* ------------------------------------------------------------------------ */
  465. /*              returns the char at the current cursor coordinates          */
  466. /* ------------------------------------------------------------------------ */
  467. int vgetchc(void)
  468. {
  469.      unsigned char far *scptr = currentpos();
  470.      return (*scptr);
  471. }
  472.  
  473. /* ------------------------------------------------------------------------ */
  474. /*        fills an area of the screen with a given char and attribute       */
  475. /* ------------------------------------------------------------------------ */
  476. void vfill(int x, int y, int yy, int xx, int c, int a)
  477.  
  478. {
  479.    char s[80];
  480.  
  481.    memset(s,c,80);
  482.    s[xx] = '\00';
  483.    while (yy)
  484.       vputs(x,y-1+(yy--),a,s);
  485. }
  486.  
  487.  
  488. /* ------------------------------------------------------------------------ */
  489. /*              pushes the screen contents to the far stack                 */
  490. /* ------------------------------------------------------------------------ */
  491. int vpushscreen(void)
  492. {
  493.      if ( ++ss > 15 ) {
  494.          ss--;
  495.          return(-1);
  496.      }
  497.      if ( (scrarray[ss] = (char far *)farmalloc(SCRSIZE) ) == NULL )
  498.         return(-2);
  499.      movedata(VIDSEGREG, 0, FP_SEG(scrarray[ss]),
  500.           FP_OFF(scrarray[ss]), 4000);
  501.      return(0);
  502. }
  503.  
  504. /* ------------------------------------------------------------------------ */
  505. /*                   pops the screen contents of the far stack              */
  506. /* ------------------------------------------------------------------------ */
  507. void vpopscreen(void)
  508. {
  509.     movedata(FP_SEG(scrarray[ss]), FP_OFF(scrarray[ss]),
  510.          VIDSEGREG, 0, SCRSIZE);
  511.     farfree(scrarray[ss]);
  512.     ss--;
  513. }
  514. /* ------------------------------------------------------------------------ */
  515. /*                        get cursor shape and position                     */
  516. /* ------------------------------------------------------------------------ */
  517. static void near getcursor(void)
  518.  
  519. {
  520.     getvmode();
  521.     _AH = READCURSOR;
  522.     _BX = vpage;
  523.     geninterrupt(VIDEO);
  524. }
  525.  
  526. /* ------------------------------------------------------------------------ */
  527. /*                    interrupt to produce 350 scan lines                   */
  528. /* ------------------------------------------------------------------------ */
  529. static void scan350(void)
  530.  
  531. {
  532.     _AX = 0x1201;
  533.     _BL = 0x30;
  534.     geninterrupt(VIDEO);
  535. }
  536.  
  537. /* ------------------------------------------------------------------------ */
  538. /*                    interrupt to produce 400 scan lines                   */
  539. /* ------------------------------------------------------------------------ */
  540. static void scan400(void)
  541. {
  542.     _AX = 0x1202;
  543.     _BL = 0x30;
  544.     geninterrupt(VIDEO);
  545. }
  546.  
  547. /* ------------------------------------------------------------------------ */
  548. /*                  get the video mode and page from BIOS                   */
  549. /* ------------------------------------------------------------------------ */
  550. static void getvmode(void)
  551.  
  552. {
  553.     _AH = 15;
  554.     geninterrupt(VIDEO);
  555.     vmode = _AL;
  556.     vpage = _BX;
  557.     vpage &= 0xFF00;
  558.     vmode &= 0x7F;
  559. }
  560.  
  561. /* ------------------------------------------------------------------------ */
  562. /*                     return the current curosr position                   */
  563. /* ------------------------------------------------------------------------ */
  564. static unsigned char far *currentpos (void)
  565. {
  566.   _AH = 0x03;
  567.   _BX = 0x00;
  568.   geninterrupt(VIDEO);
  569.   return (scrptr( _DL+1, _DH+1 ) );
  570. }
  571.  
  572. /* ------------------------------------------------------------------------ */
  573. /*           returns the video address for the  given coordinates           */
  574. /* ------------------------------------------------------------------------ */
  575. static unsigned char far *scrptr (int x, int y)
  576.  
  577. {
  578.    return (VIDSEG + (y * (SCREENWIDTH*2)) + (x << 1) );
  579. }
  580.  
  581. /* ------------------------------------------------------------------------ */
  582. /*                   puts the current date out to the screen                */
  583. /*      1 = dd-mm-yy       2 = dd mmm yyyy   3 = mm-dd-yy    4 = yy-mm-dd      */
  584. /* ------------------------------------------------------------------------ */
  585. void vputdate(int x, int y, int attr, int fmt )
  586. {
  587.   char *MonthArray[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  588.                "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  589.   struct date dt;
  590.  
  591.   getdate(&dt);
  592.   switch(fmt) {
  593.      case 1:
  594.          vputf(x, y, attr,"%2d-%02d-%02d", dt.da_day, dt.da_mon,
  595.            dt.da_year % 100 );
  596.          break;
  597.      case 2:
  598.          vputf(x, y, attr,"%2d %3s %04d", dt.da_day,
  599.            MonthArray[dt.da_mon-1], dt.da_year );
  600.          break;
  601.      case 3:
  602.          vputf(x, y, attr,"%02d-%2d-%02d", dt.da_mon, dt.da_day,
  603.            dt.da_year % 100 );
  604.          break;
  605.      case 4:
  606.          vputf(x, y, attr,"%02d-%02d-%2d", dt.da_year % 100 , dt.da_mon,
  607.            dt.da_day);
  608.          break;
  609.     }
  610. }
  611.  
  612. /* ------------------------------------------------------------------------ */
  613. /*                     puts the current time onto the screen                */
  614. /*                 1 = hh:mm:ss (military)   2 = hh:mm    (military)          */
  615. /*           3 = hh:mm:ss AM/PM        4 = hh:mm    AM/PM               */
  616. /* ------------------------------------------------------------------------ */
  617. void vputtime(int x, int y, int attr, int fmt)
  618. {
  619.    struct time tm;
  620.    char c;
  621.  
  622.    gettime(&tm);
  623.    switch(fmt) {
  624.     case 1:
  625.         vputf(x, y, attr,"%2d:%02d:%02d",
  626.             tm.ti_hour, tm.ti_min, tm.ti_sec );
  627.         break;
  628.     case 2:
  629.         vputf(x, y, attr,"%2d:%02d",tm.ti_hour, tm.ti_min );
  630.         break;
  631.     case 3:
  632.         c = 'A';
  633.         if ( tm.ti_hour > 11 ) {
  634.             c = 'P';
  635.             tm.ti_hour -= 12;
  636.         }
  637.         if ( tm.ti_hour == 0 )  tm.ti_hour = 12;
  638.         vputf(x, y, attr,"%2d:%02d:%02d %cM",
  639.             tm.ti_hour, tm.ti_min, tm.ti_sec, c );
  640.         break;
  641.     case 4:
  642.         c = 'A';
  643.         if ( tm.ti_hour > 11 ) {
  644.             c = 'P';
  645.             tm.ti_hour -= 12;
  646.         }
  647.         if ( tm.ti_hour == 0 )  tm.ti_hour = 12;
  648.         vputf(x, y, attr,"%2d:%02d %cM",
  649.             tm.ti_hour, tm.ti_min, c );
  650.         break;
  651.    }
  652. }
  653.  
  654. /* ------------------------------------------------------------------------ */
  655. /*                           makes a beep noise                             */
  656. /* ------------------------------------------------------------------------ */
  657. void vbeep(int m)
  658. {
  659.    if (m)    {
  660.      sound(2000);
  661.      delay(100);
  662.    }
  663.    else {
  664.     sound(500);
  665.     delay(250);
  666.   }
  667.  nosound();
  668. }
  669.  
  670.